<?

    include ("htmlparser.inc");
    
    //define("ROOT", 'http://deviet.ucdavis.edu');
    define("BASE_URL", 'http://deviet.ucdavis.edu/');
    
    $BASE_URL = "http://devftg.ucdavis.edu/"; //TODO determine later from root URL
    
    //list of all URLS; keys are link text
    $link_names = array();
    
    //list of all link text; keys are URLS
    $link_urls  = array();
    
    //list of all visited links
    $visited_links = array();
    
    //list of links to visit
    $to_visit = array();
    
    //maintain a list of broken links
    $broken = array();

    function getAbsolutePath($url, $relative_url){
    	/**
    	 * Takes a URL, and retrieves the path minus the file.
    	 * Probably not the most efficient way to do this
    	 * @param string $url URL to retrieve the path from
    	 * @param integer $relative_url url we have read in; need to check for levels up (e.g., '../../..')
    	 * @return string
    	 */
    	
    	//check how many levels up we should go, if any
    	$count = substr_count($relative_url, '../');
    	
    	$pieces = explode('/', $url);
    	$ret = '';
    	
    	for($i = 0; $i < count($pieces) - (1 + $count); $i++)
    		$ret .= $pieces[$i] . "/";
    		
    	return $ret;
    }
    
    function checkPage($main_url){
    		set_time_limit(0);
    		
    	/**
    	 * Outputs a list of all 'errors' on a page
    	 * @param string $main_url The URL of the page to check
    	 * @return none
    	 */
    	
    	//echo $main_url . "<br>";
    	
    	//refer to variables in the global scope
    	global $link_names;
    	global $link_urls;
    	global $visited_links;
    	global $to_visit;
    	global $broken;

    	$parser = HtmlParser_ForURL ($main_url);
    	if($parser == null)
    		$broken[$main_url] = 1;
    	
    	while ($parser != null and $parser->parse()) {      
    		//if the element is an anchor tag...
    		
	        if ($parser->iNodeType == NODE_TYPE_ELEMENT and strtolower($parser->iNodeName) == "a") {      		
	                $url = $parser->iNodeAttributes["href"];	
	                
	                //if we haven't visited the link, add it to the 'to_visit' array
	                //first though, make sure that it's an absolute link; if not, make it one
	                //also make sure the link is in the root domain
	                if(!strstr($url, "http")){
	                	//don't allow duplicate slashes to happen
	                	if($url[0] == "/")
	                		$url = substr($url, 1, 9999);

	                	 //remove any '..' from the $url
	               		 $url = getAbsolutePath($main_url, $url) . str_replace('../', '', $url);
	               		 
	               		
	                }
	                
	                //add the link to the 'to visit' list IF it's on the same domain and is not a PDF (or other file type TODO)
	                if(!isset($visited_links[$url]) and strstr($url, BASE_URL) and !strstr($url, ".pdf"))
	                	$to_visit[$url] = 1;
	                	
	                //previous element was an anchor; parse the next token and grab the text
	                $parser->parse();
	                if($parser->iNodeType == NODE_TYPE_TEXT){
	                	
	                	/////////////////////////////////////////////////////////////////////////////
	                	//check to see if this text already exists
	                	//if the link exists and the URL is different, show error; else, set it
	                	
	                	//keep grabbing text until we hit the end of the link
	                	$text = '';
	                	
	                	while($parser->iNodeType != NODE_TYPE_ENDELEMENT){
	                		$text .= $parser->iNodeValue . ' ';
	                		$parser->parse();
	                	}
	                	
	                	//echo "<b>$text <a href = $main_url>$main_url</a></b><br>";
	                	
	                	if(isset($link_names[$text])){
	                		
	                		//add this link url to the end of the list if we haven't seen it before
	                		//strip out all slashes because they were causing problems (e.g., http://google.com SHOULD equal http://google.com/
	                		if(!strstr(str_replace('/', '', $link_names[$text]), str_replace('/', '', $url)))
	                			$link_names[$text] .= " ||| <u>$text</u> (<a href = $url>$url</a>) CONTEXT: <a href = $main_url>$main_url</a>";
	                	}
	                	else{
	                		
	                		//make sure it doesn't point to itself
	                		if($url != $main_url)
	                			$link_names[$text] = "<u>$text</u> (<a href = $url>$url</a>) CONTEXT: <a href = $main_url>$main_url</a>";
	                	}
	                	
	                	////////////////////////////////////////////////////////////////////////////////
	                	//check to see if the link text is different from known URLs (And not itself)
	                	if(isset($link_urls[$url])){
	                		
	                		//add this link text to the end of the list if we haven't seen it before
	                		if(!strstr($link_urls[$url], $text)){
	                			
	                			$link_urls[$url] .= " ||| <u>$text</u> (<a href = $url>$url</a>) CONTEXT: <a href = $main_url>$main_url</a>";
	                			//echo "*** $text ||| " . $link_urls[$url] . "<br>";
	                		}
	                	}
	                	else{
	                		$link_urls[$url] = "<u>$text</u> (<a href = $url>$url</a>) CONTEXT: <a href = $main_url>$main_url</a>";	
	                		//print_r($link_urls);	
	                	}	       			
	                } //end if text node
	        } //end if anchor
	    } //end while
	    
	    //page has been parsed... parse the next one
	    //if the current page is in 'to_visit', remove it
	    if(isset($to_visit[$main_url]))
	    	unset($to_visit[$main_url]);
	    	
	    //add to visited list
	    $visited_links[$main_url] = 1;
	    	
	    $keys = array_keys($to_visit);
	    foreach($keys as $site)
	    	if(!isset($visited_links[$site]))
	    		checkPage($site);
	    
    } //end function

 	checkPage("http://deviet.ucdavis.edu/");
	    
    echo "<h1>Summary</h1>";
    echo "Use this tool to help find inconsistencies in a site (the same link pointing multiple places; the same place referenced by multiple links).  Note: This tool is just a guide; oftentimes false positives are generated, so all 'warnings' should be manually visited by testers to verify their accuracy.<br><br>";
    echo "Please email comments or questions to ejfarraro at ucdavis dot edu<br><br>";
    echo "<h3>Using Root URL:<u> " . BASE_URL . "</u></h3>";
    echo "<hr>";
    echo "<h2>The following links have the same link text, but different URLS</h2>";
    $keys = array_keys($link_names);
    foreach($keys as $k){
    	//echo $link_names[$k] . "<br>";
    	
    	$matches = explode("|||", $link_names[$k]);
    	   	
    	//don't display email addresses -- they are incorrectly handled
    	if(count($matches) > 1 and !strstr($k, '@')){
    		echo "<h3>$k</h3>";
    		echo "<ul>";
    		foreach($matches as $m){
    			echo "<li>$m</li>";
    		}
    		echo "</ul>";
    	}
    }
    
    echo"<hr>";
    echo "<h2>The following links have the same URL, but different link text</h2>"	;
	$keys = array_keys($link_urls);
    foreach($keys as $k){
    	//echo $link_names[$k] . "<br>";
    	
    	$matches = explode("|||", $link_urls[$k]);
    	
    	//don't display email addresses -- they are incorrectly handled
    	if(count($matches) > 1 and !strstr($k, '@')){
    		echo "<h3>$k</h3>";
    		echo "<ul>";
    		foreach($matches as $m){
   				echo "<li>$m</li>";
    		}
    		echo "</ul>";
    	}
    }
    
    echo "<hr>";
    echo "<h2>The following links were (probably) not found</h2>";
    //don't display any link with an @... it's probably an email address
    $keys = array_keys($broken);
    foreach($keys as $k){
    	if(!strstr($k, '@'))
    		echo "<a href = $k>$k</a><br> ". strstr('@', $k);
    }


?>

